


/**************************************************START OF FILE*****************************************************/



/*------------------------------------------------------------------------------------------------------------------
Includes
*/

#include "stm32f0xx_hal.h"
#include "xBsp_Hcs301.h"


/*------------------------------------------------------------------------------------------------------------------
Definitions
*/
#define LED_ON 			GPIO_PIN_RESET
#define LED_OFF 		GPIO_PIN_SET

#define LED_SET_ERR_Status(Status)	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, Status);
#define LED_SET_OK_Status(Status)	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, Status);

//用来判断写数据是否完成
uint8_t isWriteFinish = 1;
//判断写入数据是否Ok
uint8_t isWriiteOk = 0 ; 




/*------------------------------------------------------------------------------------------------------------------
Variables
*/

TIM_HandleTypeDef htim14;



uint16_t ReceiveData[12];		//校验时读取到的数据

uint16_t WriteDataBuffer[12] = 	//写入的数据
{
	0x1234,		//key_0
	0x5678, 	//key_1
	0x1234, 	//key_2
	0x5678,		//key_3
	0xA000,		//SYNC
	0x0000,		//RES
	0xABCD,		//SER_0 序列号
	0x8234,		//SER_1	序列号
	0xFFFF, 	//SEED_0 种子
	0xFFFF,		//SEED_1 种子
	0x0000, 	//RES
	0x1FFF,		//CONFIG
};



uint8_t HCS301_ProgramStep = 0;		//编程状态机
uint8_t CurrentWriteBit = 0;		//当前写到那个bit
uint16_t CurrentReadBit = 0;		//当前读到那个bit
uint16_t CurrentWriteIndex = 0;		//当前写到那个word





/*------------------------------------------------------------------------------------------------------------------
Code
*/
void xSys_HCS301_Program(void);
void WriteData(void);
void ReadData(void);



/*
*********************************************************************************************************************

@ Brief  : 初始化HCS301通讯相关的芯片外设

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-04 16:28

*********************************************************************************************************************
*/
void xBSP_HCS2301_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStruct = {0};

	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOF_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();

	__HAL_RCC_TIM14_CLK_ENABLE();


	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);



	/*Configure GPIO pin : PA0 */
	GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	htim14.Instance = TIM14;
	htim14.Init.Prescaler = 48-1;						//时钟输入是48M的。
	htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
	htim14.Init.Period = 65535;
	htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
	htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
	if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
	{
		while (1);
	}

	HAL_TIM_Base_Stop(&htim14);



	//打开中断
	__HAL_TIM_CLEAR_IT(&htim14 , TIM_IT_UPDATE);
	__HAL_TIM_ENABLE_IT(&htim14 , TIM_IT_UPDATE);


	//设置定时器中断优先级
	HAL_NVIC_SetPriority(TIM14_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(TIM14_IRQn);

}


void xBSP_HCS301_SetIntTime(uint16_t us)
{
	HAL_TIM_Base_Stop(&htim14);
	TIM14->ARR = us;
	TIM14->CNT = 0X00;
	HAL_TIM_Base_Start(&htim14);
}


/*
*********************************************************************************************************************

@ Brief  : 定时器中断函数

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-04 16:32

*********************************************************************************************************************
*/
void TIM14_IRQHandler(void)
{

	HAL_TIM_IRQHandler(&htim14);
	HAL_TIM_Base_Stop(&htim14);
	
	xSys_HCS301_Program();
}

/*
*********************************************************************************************************************

@ Brief  : 操作两个gpio

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-04 18:08

*********************************************************************************************************************
*/
inline void xBSP_HCS301_SetDataIo(uint8_t status)
{
	HAL_GPIO_WritePin(GPIOA , GPIO_PIN_3 , (GPIO_PinState)status);
}

inline void xBSP_HCS301_SetClockIo(uint8_t status)
{
	HAL_GPIO_WritePin(GPIOA , GPIO_PIN_2 , (GPIO_PinState)status);
}

inline uint8_t xBSP_HCS301_GetDataIo(void)
{
	return HAL_GPIO_ReadPin(GPIOA , GPIO_PIN_3);
}

void xBSP_HCS301_DataIoInputModle(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void xBSP_HCS301_DataIoOutputModle(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}



/*
*********************************************************************************************************************

@ Brief  : 开始写入HCS301

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-19 15:10

*********************************************************************************************************************
*/
void xBSP_HCS301_StartProgram(void)
{
	HCS301_ProgramStep = 0;
	CurrentWriteBit = 0;
	xBSP_HCS301_DataIoOutputModle();
	xBSP_HCS301_SetIntTime(1000);

	LED_SET_ERR_Status(LED_OFF);
	LED_SET_OK_Status(LED_OFF);

    //标记没有发送完成
    isWriteFinish = 0;
}




/*
*********************************************************************************************************************

@ Brief  : 写入HCS301的主要状态机

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-19 15:11

*********************************************************************************************************************
*/
void xSys_HCS301_Program(void)
{
	switch (HCS301_ProgramStep)
	{
		case 0:
			xBSP_HCS301_SetClockIo(0);
			xBSP_HCS301_SetDataIo(0);
			xBSP_HCS301_SetIntTime(1000 * 10);
			HCS301_ProgramStep++;
		break;
		//Tps
		case 1:
			xBSP_HCS301_SetClockIo(1);
			xBSP_HCS301_SetDataIo(0);
			xBSP_HCS301_SetIntTime(1000 * 4);
			HCS301_ProgramStep++;
		break;
		//Tph1
		case 2:
			xBSP_HCS301_SetClockIo(1);
			xBSP_HCS301_SetDataIo(1);
			xBSP_HCS301_SetIntTime(1000 * 4);
			HCS301_ProgramStep++;
		break;
		//Tph2
		case 3:
			xBSP_HCS301_SetClockIo(1);
			xBSP_HCS301_SetDataIo(0);
			xBSP_HCS301_SetIntTime(300);
			HCS301_ProgramStep++;
		break;
		//Tpbw
		case 4:
			xBSP_HCS301_SetClockIo(0);
			xBSP_HCS301_SetDataIo(0);
			xBSP_HCS301_SetIntTime(5000);
			HCS301_ProgramStep++;
			CurrentWriteBit = 0;
            CurrentWriteIndex = 0;
		break;
		//写入数据
		case 5:
			WriteData();
		break;

		//校验数据
		case 6:
			xBSP_HCS301_SetClockIo(0);
			xBSP_HCS301_SetDataIo(0);
			//设置为输入模块
			xBSP_HCS301_DataIoInputModle();
			xBSP_HCS301_SetIntTime(100);
			HCS301_ProgramStep++;

		break;

		case 7:
			ReadData();
		break;

		//结束，停止状态
		case 8:

            isWriteFinish = 1;
			for (uint8_t i = 0; i < 12; i++)
			{
				if(ReceiveData[i] != WriteDataBuffer[i])
				{
					LED_SET_ERR_Status(LED_ON);
					LED_SET_OK_Status(LED_OFF);
                    isWriiteOk = 0;
					HCS301_ProgramStep = 9;
					return;
				}
			}

			LED_SET_ERR_Status(LED_OFF);
			LED_SET_OK_Status(LED_ON);
            isWriiteOk = 1;
			HCS301_ProgramStep = 9;
		break;
	}
}





void WriteData(void)
{

	if(CurrentWriteBit % 2 == 0)
	{
		//数据变化
		xBSP_HCS301_SetClockIo(1);

		if(WriteDataBuffer[CurrentWriteIndex] & (0x01 <<  (CurrentWriteBit/2)))
		{
			xBSP_HCS301_SetDataIo(1);	
		}
		else
		{
			xBSP_HCS301_SetDataIo(0);
		}
		
	}
	else
	{
		//写入数据
		xBSP_HCS301_SetClockIo(0);
	}
	
	xBSP_HCS301_SetIntTime(100);

	CurrentWriteBit++;

	if(CurrentWriteBit == 32)
	{
		xBSP_HCS301_SetIntTime(1000 * 60);
		CurrentWriteBit = 0;
		CurrentWriteIndex++;
		if(CurrentWriteIndex == 12)
		{
			CurrentReadBit = 0;
			HCS301_ProgramStep++;
		}
		
		
	}
}










/*
*********************************************************************************************************************

@ Brief  : 读取芯片的数据，用于校验

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-08-19 15:11

*********************************************************************************************************************
*/
void ReadData(void)
{
	static uint16_t ReadBitIndex = 0;	//当前读那个bit
	static uint16_t ReadByteIndex = 0;	//当前读那个byte

	if(CurrentReadBit % 2 == 0)
	{
		//读取数据
		xBSP_HCS301_SetClockIo(1);
		ReadBitIndex = CurrentReadBit / 2;

		ReadByteIndex = ReadBitIndex / 16;
		ReadBitIndex = ReadBitIndex % 16;

		if(xBSP_HCS301_GetDataIo())
		{
			ReceiveData[ReadByteIndex] |=  (0x01 << ReadBitIndex);
		}
		else
		{
			ReceiveData[ReadByteIndex] &=  ~(0x01 << ReadBitIndex);
		}
	}
	else
	{
		
		xBSP_HCS301_SetClockIo(0);
	}

	CurrentReadBit++;
	xBSP_HCS301_SetIntTime(100);

	if(CurrentReadBit == 192*2)
	{
		HCS301_ProgramStep++;
	}

}



/**************************************************END OF FILE*******************************************************/

